package com.california.payopenapi.controller;

import com.california.pay.model.PersonOrderPayRsp;
import com.california.payopenapi.common.ServerResponse;
import com.california.payopenapi.entity.PayOrderRequest;
import com.california.payopenapi.exception.SystemException;
import com.california.payopenapi.service.PayService;
import com.california.payopenapi.utils.Base64Util;
import com.california.payopenapi.utils.JsonUtil;
import com.california.payopenapi.utils.PropertiesUtil;
import com.california.payopenapi.vo.AppRequestPayParamsVo;
import com.california.payopenapi.vo.AppRequestPayResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;

/**
 * @Description: 支付controller
 * @author: KeyboardMan
 * @Date: Create in 2018-12-05:21:00
 */
@Slf4j
@Controller
@RequestMapping("/gateway")
public class PayController {

    @Autowired
    private PayService payService;

    @RequestMapping(value = "/getQR", method = RequestMethod.POST)
    public ModelAndView pay(@Valid @RequestBody PayOrderRequest payOrderRequest) throws InvocationTargetException, IllegalAccessException, IntrospectionException {
        PersonOrderPayRsp personOrderPayRsp = payService.getPayInfo(payOrderRequest);
        log.info("返回的对象 {}",personOrderPayRsp);
        ModelAndView modelAndView = new ModelAndView("pay");
        StringBuffer createQrCodeUrl = new StringBuffer(PropertiesUtil.getProperty("create.qrcode.url"));
        createQrCodeUrl.append("/"+personOrderPayRsp.getChannelUserId());
        createQrCodeUrl.append("/"+personOrderPayRsp.getInnerOrderNo());
        createQrCodeUrl.append("/"+personOrderPayRsp.getAmount());
        modelAndView.addObject("src",createQrCodeUrl.toString());
        modelAndView.addObject("orderNo",personOrderPayRsp.getInnerOrderNo());
        modelAndView.addObject("amount",personOrderPayRsp.getAmount().doubleValue()/100);
        modelAndView.addObject("returnUrl",payOrderRequest.getReturnUrl());
        return modelAndView;
    }


    @RequestMapping(value = "/createQrCode/{userId}/{orderNo}/{amount}")
    @ResponseBody
    public ResponseEntity<byte[]> createQrCode(@PathVariable("userId") String userId,
                                      @PathVariable("orderNo") String orderNo,
                                      @PathVariable("amount") Long amount) {
        byte[] imgBytes = payService.getPayQrCodeImg(userId, orderNo, amount);
        HttpHeaders headers = new HttpHeaders();// 设置一个head
        headers.setContentDispositionFormData("attachment", UUID.randomUUID().toString()+".png");// 随缘命名
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);// 内容是字节流
        return new ResponseEntity<>(imgBytes, headers, HttpStatus.OK);// 开始下载
    }

    @RequestMapping("/pay/{userId}/{orderNo}/{amount}/{token}")
    public ModelAndView pay(@PathVariable("userId") String userId,
                            @PathVariable("orderNo") String orderNo,
                            @PathVariable("amount") Long amount,
                            @PathVariable("token") String token) {
        log.info("支付参数 userId = {}  ,orderNo = {}  ,amount = {}  ,token = {}",userId,orderNo,amount,token);
        if (!payService.checkPay(orderNo, token)) {
            throw new SystemException("token校验异常, 支付失败");
        }
        ModelAndView modelAndView = new ModelAndView("mysterious_code");
        String price = "\""+amount.doubleValue()/100+"\"";
        modelAndView.addObject("amount",price);
        modelAndView.addObject("orderNo",orderNo);
        modelAndView.addObject("userId",userId);
        return modelAndView;
    }


    /**
     * APP 对接方使用接口, 对方无法解析HTML
     * @param payOrderRequest
     * @return
     */
    @RequestMapping(value = "/executePay", method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse appRequestPay(@Valid @RequestBody PayOrderRequest payOrderRequest) {
        PersonOrderPayRsp personOrderPayRsp = payService.getPayInfo(payOrderRequest);
        log.info("返回的对象 {}",personOrderPayRsp);
        StringBuffer createQrCodeUrl = new StringBuffer(PropertiesUtil.getProperty("create.qrcode.url"));
        createQrCodeUrl.append("/"+personOrderPayRsp.getChannelUserId());
        createQrCodeUrl.append("/"+personOrderPayRsp.getInnerOrderNo());
        createQrCodeUrl.append("/"+personOrderPayRsp.getAmount());
        AppRequestPayParamsVo payParamsVo = new AppRequestPayParamsVo();
        payParamsVo.setSrc(createQrCodeUrl.toString());
        payParamsVo.setAmount((personOrderPayRsp.getAmount()));
        payParamsVo.setOrderNo(personOrderPayRsp.getInnerOrderNo());
        payParamsVo.setReturnUrl(payOrderRequest.getReturnUrl());
        String params = Base64Util.encode(JsonUtil.obj2String(payParamsVo));
        String url = PropertiesUtil.getProperty("app_pay_url")+params;
        return ServerResponse.createBySuccess(new AppRequestPayResultVo(url));
    }


    @RequestMapping(value = "/appPay/{params}", method = RequestMethod.GET)
    public ModelAndView appPay(@PathVariable("params") String params) {
        String decode = Base64Util.decode(params);
        AppRequestPayParamsVo paramsVo;
        try {
            paramsVo = JsonUtil.string2Obj(decode,AppRequestPayParamsVo.class);
        } catch (Exception e) {
            log.error("app 支付接口参数转成JSON异常  {}",e);
            throw new SystemException("参数转换异常，请重新确认参数");
        }
        ModelAndView modelAndView = new ModelAndView("pay");
        modelAndView.addObject("src",paramsVo.getSrc());
        modelAndView.addObject("orderNo",paramsVo.getOrderNo());
        modelAndView.addObject("amount",paramsVo.getAmount().doubleValue()/100);
        modelAndView.addObject("returnUrl",paramsVo.getReturnUrl());
        return modelAndView;
    }

}